<h1>Further tips</h1>

<h2>Symfony integration</h2>

<p>
    Activating <b>Aspect PHP</b> for a <b>Symfony</b> project is really easy.
    Just add the following lines to your <i>ProjectConfiguration.class.php</i>
    in your main <i>config</i> directory:
</p>

<div class="code">
    <code>
        <small>ProjectConfiguration.class.php</small><br />
        require_once dirname(__FILE__) . '/../lib/vendor/aspect_php/lib/aspectAutoloader.php';<br />
        aspectAutoloader::register();<br />
        <br />
        class ProjectConfiguration extends sfProjectConfiguration {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function setup() {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>// Your own setup...</b><br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this->initializeAspectContainer();<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;/**<br />
        &nbsp;&nbsp;&nbsp;&nbsp; * Aspect container<br />
        &nbsp;&nbsp;&nbsp;&nbsp; */<br />
        &nbsp;&nbsp;&nbsp;&nbsp;protected function initializeAspectContainer() {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($this instanceof sfApplicationConfiguration) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$debug = sfConfig::get('sf_debug');<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$filename = sfConfig::get('sf_cache_dir') . '/myAspectContainer.php';<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!$debug && file_exists($filename)) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require_once $filename;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$aspectContainer = new myAspectContainer();<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$aspectContainer = new aspectContainerBuilder('FooAspect');<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!$debug) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$dumper = new aspectContainerDumper($aspectContainer);<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$code = $dumper->dump('myAspectContainer');<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file_put_contents($filename, $code);<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p>
    and copy the <b>Aspect PHP</b> library files in an <i>aspect_php</i>
    directory located in your <i>lib/vendor</i> directory.
</p>

<p class="warning">
    Don't forget to instantiate your targeted classes through the
    <b>Aspect PHP</b> proxy or your calls won't be intercepted:
    <code>$myInstance&nbsp;=&nbsp;new aspectProxy(new myClass());</code>
</p>

<h2>Hacking Aspect PHP</h2>

<h3>Scanning a directory for aspect classes</h3>

<p>
    You might find quite tedious to add every single aspect class to your
    <i>aspectContainerBuilder</i> everytime you create a new one:
</p>

<div class="code">
    <code>
        $aspectContainer = new aspectContainerBuilder(<br />
        &nbsp;&nbsp;'FooAspect',<br />
        &nbsp;&nbsp;'FooOtherAspect',<br />
        &nbsp;&nbsp;'FooSecurityAspect',<br />
        &nbsp;&nbsp;'FooTemplatingAspect',<br />
        &nbsp;&nbsp;'FooBlablablaAspect',<br />
        &nbsp;&nbsp;...<br />
        );<br />
    </code>
</div>

<p>
    So if you decide to put all your aspect classes in some well-known
    directories (keep in mind though that <b>AOP</b> aims to separate concerns
    so putting all your aspect classes in one unique directory might not be the
    best thing to do), here's a solution: create a <b>PHP</b> class called
    <i>myAspectContainer</i>:
</p>

<div class="code">
    <code>
        <small>myAspectContainer.class.php</small><br />
        class myAspectContainer extends aspectContainerBuilder {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function __construct() {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$aspectDirectories = array(<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirname(__FILE__) . '/path/securityAspect',<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirname(__FILE__) . '/path/loggingAspect',<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dirname(__FILE__) . '/path/fooAspect'<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$aspectClasses = array();<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach ($aspectDirectories as $aspectDirectory) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$folder = opendir($aspectDirectory);<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ($file = readdir($folder)) {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!in_array($file, array('.', '..'))) {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (preg_match('/\.class\.php$/', $file)) {<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require_once $aspectDirectory . '/' . $file;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$aspectClasses[] = preg_replace('/\.class\.php$/', '', $file);<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;closedir($folder);<br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent::__construct($aspectClasses);<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p class="notice">
    Don't forget that if you use the cache system, this scanning action will
    only be required once!
</p>

<p>
    Now just call this custom aspect container builder instead of the original
    <i>aspectContainerBuilder</i> and your <b>PHP</b> aspect classes will be
    automatically loaded!
</p>

<h3>Using Symfony Dependency Injection Container</h3>

<p>
    If you like to use a dependency injection container in your projects, you
    might want to be able to use it to inject dependencies to your aspect
    classes. So here's a very simple way to do it with the great
    <a href="http://components.symfony-project.org/dependency-injection/">dependency
        injection container</a> of <b>Symfony</b>.
</p>

<p>
    Creates a new <b>PHP</b> class called <i>myAspectContainer</i> and paste the
    following code:
</p>

<div class="code">
    <code>
        <small>myAspectContainer.class.php</small><br />
        class myAspectContainer extends aspectContainerBuilder {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;public function getAspectClassInstance($serviceName) {<br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sfApplicationConfiguration::getActive()->getServiceContainer()->$serviceName;<br />
        &nbsp;&nbsp;&nbsp;&nbsp;}<br />
        <br />
        }<br />
    </code>
</div>

<p class="notice">
    Here the expression
    <code>sfApplicationConfiguration::getActive()->getServiceContainer()</code>
    is the way in my application to refer to the service container. So replace
    this line with your own dependency injection container.
</p>

<p>
    Now all you have to do is calling this custom aspect container builder
    you've just written instead of the original <i>aspectContainerBuilder</i>
    and you're ready to use injection in your aspect classes.
</p>

<p>
    Another useful thing about dependency injection, is that it can
    automatically 'proxified' your classes in a totally transparent way. Just
    edit the configuration file for the dependency injection container and add
    a parameter for the <i>aspectProxy</i> class:
</p>

<div class="code">
    <code>
        &lt;?xml version="1.0" ?><br />
        <br />
        &lt;container xmlns="http://symfony-project.org/2.0/container"><br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&lt;parameters><br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;parameter key="proxy.class">aspectProxy&lt;/parameter><br />
        &nbsp;&nbsp;&nbsp;&nbsp;&lt;/parameters><br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&lt;services><br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;service id="myService.impl" class="myServiceClass" /><br />
        <br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;service id="myService" class="%proxy.class%"><br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;argument type="service" id="myService.impl" /><br />
        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/service><br />
        &nbsp;&nbsp;&nbsp;&nbsp;&lt;/services><br />
        <br />
        &lt;/container><br />
    </code>
</div>

<p class="notice">
    Now accessing <code>myService</code> through the dependency injection
    container will automatically give you the 'proxified' class.
</p>

<p>
    Combining this tip with the 'Scanning a directory for aspect classes' one
    and the <b>Aspect PHP</b> caching system, you now have a fully transparent
    and fast <b>AOP</b> component for your application!
</p>